package br.com.honorato.view;

import java.io.IOException;
import java.util.Iterator;

import javax.faces.FacesException;
import javax.faces.application.ViewExpiredException;
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerWrapper;
import javax.faces.context.FacesContext;
import javax.faces.event.ExceptionQueuedEvent;
import javax.faces.event.ExceptionQueuedEventContext;
import javax.servlet.http.HttpSession;

public class ViewExpiredExceptionExceptionHandler extends ExceptionHandlerWrapper {

	private ExceptionHandler wrapped;

	public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) 
	{
		this.wrapped = wrapped;
	}

	@Override
	public ExceptionHandler getWrapped() 
	{
		return this.wrapped;
	}

	@Override
	public void handle() throws FacesException 
	{

		FacesContext facesContext = FacesContext.getCurrentInstance();
		Iterator<ExceptionQueuedEvent> eventIterator = getUnhandledExceptionQueuedEvents().iterator();
		ViewExpiredException viewExpiredException = getViewExpiredException(getUnhandledExceptionQueuedEvents());
		if (viewExpiredException != null) 
		{
			String redirectUrl = invalidateSessionAndGetErrorPage(facesContext, viewExpiredException);
			redirectToTheErrorPage(facesContext, redirectUrl);
		}
		else if (eventIterator.hasNext()) 
		{
			String redirectUrl = "../public/error-404.jsf";
			redirectToTheErrorPage(facesContext, redirectUrl);
		}
	}


	private String invalidateSessionAndGetErrorPage(FacesContext facesContext, ViewExpiredException throwable) 
	{
		HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
		if (session != null) 
		{
			session.invalidate();
		}

		return "/dashboard.xhtml";
	}

	@SuppressWarnings("static-access")
	private void redirectToTheErrorPage(FacesContext facesContext, String redirectUrl) 
	{
		System.out.println("redirectToTheErrorPage");
		try {
			facesContext.getCurrentInstance().getExternalContext().redirect(redirectUrl);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
//		SecurityPhaseListener spl = new SecurityPhaseListener();
//		spl.doRedirect(facesContext, redirectUrl);
//		System.out.println("redirect");
	}

	private ViewExpiredException getViewExpiredException(Iterable<ExceptionQueuedEvent> unhandledExceptionQueuedEvents) 
	{
		for (ExceptionQueuedEvent event : unhandledExceptionQueuedEvents) {
			ExceptionQueuedEventContext queuedEventContext = event.getContext();
			if (queuedEventContext.getException() instanceof ViewExpiredException) {
				return (ViewExpiredException) queuedEventContext.getException();
			}
		}
		return null;
	}
}